using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using AvansRS.Domain.DataInterface;
using StructureMap;
using AvansRS.Domain;

namespace AvansRS.Web.Controllers
{
	public class GroupController : Controller
	{
		IGroupRepository repGroup;
		IRepository<Entity> repEntity;
		IPersonRepository repPerson;
		public GroupController(IGroupRepository repGroup, IRepository<Entity> repEntity, IPersonRepository repPerson)
		{
			this.repGroup = repGroup;
			this.repEntity = repEntity;
			this.repPerson = repPerson;
		}

		public GroupController()
			: this(ObjectFactory.GetInstance<IGroupRepository>(), ObjectFactory.GetInstance<IRepository<Entity>>(), ObjectFactory.GetInstance<IPersonRepository>())
		{
		}

		public ActionResult Index()
		{
			return View(repGroup.GetAll());
		}
		
		public ActionResult Edit(int id)
		{
			Group group = repGroup.GetByID(id);
			SetGroupTypeDropDown(group.GroupType);
			return View(group);
		}

		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult Edit(Group group, string leader)
		{
			Group foundGroup = repGroup.GetByID(group.ID);
			Person foundPerson = repPerson.FindByAccountUsername(leader);
			if(foundGroup == null)
			{
				ModelState.AddModelError("ERROR", "Onbekende fout. Probeer opnieuw.");
				SetGroupTypeDropDown(group.GroupType);
				return View(foundGroup);
			}
			else if(foundPerson == null)
			{
				ModelState.AddModelError("Leader", "Onbekende gebruikersnaam.");
				SetGroupTypeDropDown(group.GroupType);
				return View(foundGroup);
			}
			else
			{
				foundGroup.Leader = foundPerson;
				foundGroup.Name = group.Name;
				foundGroup.GroupType = group.GroupType;
				repGroup.Save(foundGroup);
				return RedirectToAction("Index", "Group");
			}
		}

		public ActionResult ManageMembers(int id)
		{
			if(TempData["ModelState"] as ModelStateDictionary != null)
			{
				ModelState.Merge(TempData["ModelState"] as ModelStateDictionary);
			}
			Group group = repGroup.GetByID(id);
			return View(group);
		}

		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult ManageMembers(int id, string member)
		{
			Group foundGroup = repGroup.GetByID(id);
			Person foundPerson = repPerson.FindByAccountUsername(member);
			if(foundGroup == null)
			{
				ModelState.AddModelError("ERROR", "Onbekende fout. Probeer opnieuw.");
			}			
			if(foundPerson == null)
			{
				ModelState.AddModelError("Member", "Gebruikersnaam ongeldig.");
			}
			else
			{
				foreach(Person person in foundGroup.Members)
				{
					if(person.ID == foundPerson.ID)
					{
						ModelState.AddModelError("Member", "Gebruiker zit al in groep.");
						break;
					}
				}
				if(ModelState.IsValid)
				{
					foundGroup.Members.Add(foundPerson);
					repGroup.Save(foundGroup);
				}
			}
			return View(foundGroup);
		}

		public ActionResult DeleteMember(int groupID, int personID)
		{
			Group group = repGroup.GetByID(groupID);
			if(group == null)
			{
				ModelState.AddModelError("ERROR", "Onbekende fout. Probeer opnieuw.");
			}
			else if(group.Leader.ID == personID)
			{
				ModelState.AddModelError("Member", "Kan leider van groep niet verwijderen.");
			}
			else
			{
				bool canDelete = false;
				int index = 0;
				for(index = 0; index < group.Members.Count; index++)
				{
					if(group.Members[index].ID == personID)
					{
						canDelete = true;
						break;
					}
				}
				if(canDelete)
				{
					group.Members.RemoveAt(index);
					repGroup.Save(group);
				}
			}
			if(!ModelState.IsValid)
			{
				TempData["ModelState"] = ModelState;
			}
			return RedirectToAction("ManageMembers", new { id = groupID });
		}

		public ActionResult Create()
		{
			SetGroupTypeDropDown(GroupType.Group);
			return View(new Group());
		}

		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult Create([Bind(Exclude = "ID")] Group group, string leader)
		{
			Person foundPerson = repPerson.FindByAccountUsername(leader);
			if(foundPerson == null)
			{
				ModelState.AddModelError("Leader", "Ongeldige gebruikersnaam.");
				SetGroupTypeDropDown(group.GroupType);
				return View(group);
			}
			else
			{
				group.Leader = foundPerson;
				group.Entity = new Entity();
				group.Members = new List<Person>();
				group.Members.Add(foundPerson);
				group.Year = DateTime.Now;
				repEntity.Add(group.Entity);
				repGroup.Add(group);
				return RedirectToAction("ManageMembers", "Group", new { id = group.ID });
			}
		}

		private void SetGroupTypeDropDown(GroupType groupType)
		{
			IList<SelectListItem> groupTypeList = new List<SelectListItem>();
			groupTypeList.Add(
				new SelectListItem()
				{
					Text = GroupType.Group.ToString(),
					Value = String.Format("{0}",(int)GroupType.Group),
					Selected = (groupType == GroupType.Group)
				}
			);
			groupTypeList.Add(
				new SelectListItem()
				{
					Text = GroupType.ProjectGroup.ToString(),
					Value = String.Format("{0}", (int)GroupType.ProjectGroup),
					Selected = (groupType == GroupType.ProjectGroup)
				}
			);
			groupTypeList.Add(
				new SelectListItem()
				{
					Text = GroupType.ExcursionGroup.ToString(),
					Value = String.Format("{0}", (int)GroupType.ExcursionGroup),
					Selected = (groupType == GroupType.ExcursionGroup)
				}
			);
			groupTypeList.Add(
				new SelectListItem()
				{
					Text = GroupType.LessonGroup.ToString(),
					Value = String.Format("{0}", (int)GroupType.LessonGroup),
					Selected = (groupType == GroupType.LessonGroup)
				}
			);
			ViewData["GroupTypeList"] = groupTypeList;
		}

		#region Auto complete events
		public ActionResult FindPerson(string q)
		{ 
			IList<Person> persons = repPerson.FindMatchesByAccountUsername(q); 
			string[] usernames = new string[persons.Count];
			for(int i = 0; i < persons.Count; i++)
			{
				usernames[i] = persons[i].Account.UserName;
			}

			//return raw text, one result on each line
			return Content(string.Join("\n", usernames));
		} 

		#endregion
	}
}